<template>
  <div class="alarm-type-statistics">
    <div class="handle-num" style="color: azure;" v-if="$route.name == 'home' && showcharts">
      <div class="nums-item" v-for="item in alarmList">
        <div class="num-item-title">{{ item.title }}：</div>
        <div class="num-item-value" :style="`color:${item.color}`">
          {{ item.value }}次
        </div>
      </div>
    </div>
    <div class="top-line" v-if="showcharts">
      <div class="chart-container">
        <base-echart style="position: absolute;z-index: 888;" :show-no-data="true"
          :options="state.AlarmStatisticsOptions" height="200"></base-echart>
        <div class="route"></div>
      </div>
      <div class="chart-data">
        <div class="chart-data-item" v-for="(item, index) in thetypeofalgorithm" :key="index">
          <div class="topic">
            <div class="circle" :style="{
      backgroundColor: item.color,
    }"></div>
            <div class="title">
              {{ item.key }}
            </div>
          </div>
          <div class="data">
            <div class="text-number">
              <CountUp :end-val="item.value"></CountUp>次
            </div>
            <div class="percent-number" :style="{
      color: item.color,
    }">
              <CountUp :end-val="renderPercent(item.value)"></CountUp>%
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="alarm-container" v-if="showList">
      <div class="list-tab">
        <div class="tab-item" :class="tabIndex == 0 ? 'currentIndex' : ''" @click="change(0)">
          AI算法
        </div>
        <div class="tab-item" :class="tabIndex == 1 ? 'currentIndex' : ''" @click="change(1)">
          告警列表
        </div>
      </div>
    </div>
    <div class="type-list" v-if="showList && tabIndex == 0">
      <AIsuanFaList :data="[thetypeofalgorithm[0]]" height="clamp(20rem, 16.67vw, 40rem)"
        :itemHeight="'clamp(15.625rem, 13.02vw, 31.25rem)'" :showTitle="false" />
      <AIsuanFaList :data="[thetypeofalgorithm[1]]" heigh="clamp(13.75rem, 11.46vw, 27.5rem)"
        :itemHeight="'clamp(7.5rem, 6.25vw, 15rem)'" :showTitle="false" />
      <!-- <AIsuanFaList :data="[thetypeofalgorithm[2]]" height="clamp(6.25rem, 5.21vw, 12.5rem)"
        :itemHeight="'clamp(5rem, 4.17vw, 10rem)'" :showTitle="false" /> -->
    </div>

    <div class="alert-list" v-if="showList && tabIndex == 1">
      <alertList></alertList>
    </div>
  </div>
</template>
<script setup lang="ts">
import alertList from "../../alert/components/alertList.vue";
import {
  reactive,
  ref,
  onMounted,
  nextTick,
  onUnmounted,
  defineProps,
  watch,
} from "vue";
import { AlarmStatisticsOptions } from "./config";
import { NewGeneral } from "@/api/screen/equipment";
import { useIds } from "@/stores/screen/ids";
import pLimit from "p-limit";
import emits from "@/utils/emits";
const state = reactive<any>({ AlarmStatisticsOptions });
const { getsessionStorage } = useIds();
const tabIndex = ref(0);
defineProps({
  showList: {
    type: Boolean,
    default: true,
  },
  showcharts: {
    type: Boolean,
    default: false,
  },
});

// 数据格式
interface Data {
  name: string;
  code: string;
  icon: string;
  color: string;
  undo: number;
  total: number;
  key: string;
  parentsKey: string;
  time: string;
  data: any
}
interface Algorithm {
  key: string;
  color: string;
  value: number;
  data: any;
  algorithm_name: Array<Data>;
}
let thetypeofalgorithm = ref<any>([
  {
    key: "可燃气体浓度检测",
    algorithm_name: [
      {
        name: "可燃气体浓度异常",
        code: "HELMET",
        icon: "未戴安全帽",
        color: "rgba(0, 148, 255, 1)",
        undo: 4,
        total: 17,
        key: "",
        parentsKey: "可燃气体浓度检测",
        time: null,
        aiAlarmCountForGrade: [
          {
            title: '普通',
            grade: 'INFO',
            number: 10
          },
          {
            title: '告警',
            grade: 'WARN',
            number: 2
          },
          {
            title: '紧急',
            grade: 'ERROR',
            number: 5
          }
        ],
        data: [
          {
            equipmentName: '可燃气体报警仪(ZY100-EX)',
            resetList: [
              {
                alertID: 1,
                alertGrade: "INFO",
                alertContent: '可燃气体报警',
                alertTime: '2024-03-20 11:06',
                handleStatus: '0',
                parentsKey: "可燃气体浓度检测",
              },
              {
                alertID: 2,
                alertGrade: "ERROR",
                alertContent: '可燃气体报警',
                alertTime: '2024-03-20 12:06',
                handleStatus: '0',
                parentsKey: "可燃气体浓度检测",
              },
              {
                alertID: 3,
                alertGrade: "WARN",
                alertContent: '可燃气体报警',
                alertTime: '2024-03-20 13:06',
                handleStatus: '0',
                parentsKey: "可燃气体浓度检测",
              }
            ]
          }
        ]
      },
      {
        name: "可燃气体浓度严重超标",
        code: "REFLECTIVE_CLOTHING",
        icon: "未穿反光衣",
        color: "rgba(31, 108, 255, 1)",
        undo: 3,
        total: 6,
        key: "",
        parentsKey: "可燃气体浓度检测",
        time: null,
        aiAlarmCountForGrade: [
          {
            title: '普通',
            grade: 'INFO',
            number: 10
          },
          {
            title: '告警',
            grade: 'WARN',
            number: 2
          },
          {
            title: '紧急',
            grade: 'ERROR',
            number: 5
          }
        ],
        data: [
          {
            equipmentName: '可燃气体报警仪(ZY100-EX)',
            resetList: [
              {
                alertID: 4,
                alertGrade: "INFO",
                alertContent: '可燃气体报警',
                alertTime: '2024-03-20 11:06',
                handleStatus: '0',
                parentsKey: "可燃气体浓度检测",
              },
              {
                alertID: 5,
                alertGrade: "ERROR",
                alertContent: '可燃气体报警',
                alertTime: '2024-03-20 12:06',
                handleStatus: '0',
                parentsKey: "可燃气体浓度检测",
              },
              {
                alertID: 6,
                alertGrade: "WARN",
                alertContent: '可燃气体报警',
                alertTime: '2024-03-20 13:06',
                handleStatus: '0',
                parentsKey: "可燃气体浓度检测",
              }
            ]
          }
        ]
      }
    ],
    color: "rgba(0, 148, 255, 1)",
    value: 23,
  },
  {
    key: "四氯化碳浓度检测",
    algorithm_name: [
      {
        name: "四氯化碳浓度异常",
        code: "SIDEWALK_INTRUSION",
        icon: "车辆占道",
        color: "rgba(255, 239, 92, 1)",
        undo: 7,
        total: 20,
        key: "",
        parentsKey: "四氯化碳浓度检测",
        time: null,
        aiAlarmCountForGrade: [
          {
            title: '普通',
            grade: 'INFO',
            number: 2
          },
          {
            title: '告警',
            grade: 'WARN',
            number: 3
          },
          {
            title: '紧急',
            grade: 'ERROR',
            number: 2
          }
        ],
        data: [
          {
            equipmentName: '四氯化碳报警仪(ZY100-CCL4)',
            resetList: [
              {
                alertID: 7,
                alertGrade: "INFO",
                alertContent: '四氯化碳报警',
                alertTime: '2024-03-20 11:06',
                handleStatus: '0',
                parentsKey: "四氯化碳浓度检测",
              },
              {
                alertID: 8,
                alertGrade: "ERROR",
                alertContent: '四氯化碳报警',
                alertTime: '2024-03-20 12:06',
                handleStatus: '0',
                parentsKey: "四氯化碳浓度检测",
              },
              {
                alertID: 9,
                alertGrade: "WARN",
                alertContent: '四氯化碳报警',
                alertTime: '2024-03-20 13:06',
                handleStatus: '0',
                parentsKey: "四氯化碳浓度检测",
              }
            ]
          }
        ]
      },
      {
        name: "四氯化碳浓度严重超标",
        code: "TRUNAROUND",
        icon: "车辆调头",
        color: "rgba(255, 248, 189, 1)",
        undo: 5,
        total: 30,
        key: "",
        parentsKey: "四氯化碳浓度检测",
        time: null,
        aiAlarmCountForGrade: [
          {
            title: '普通',
            grade: 'INFO',
            number: 3
          },
          {
            title: '告警',
            grade: 'WARN',
            number: 2
          },
          {
            title: '紧急',
            grade: 'ERROR',
            number: 4
          }
        ],
        data: [
          {
            equipmentName: '四氯化碳报警仪(ZY100-CCL4)',
            resetList: [
              {
                alertID: 10,
                alertGrade: "INFO",
                alertContent: '四氯化碳报警',
                alertTime: '2024-03-20 11:06',
                handleStatus: '0',
                parentsKey: "四氯化碳浓度检测",
              },
              {
                alertID: 11,
                alertGrade: "ERROR",
                alertContent: '四氯化碳报警',
                alertTime: '2024-03-20 12:06',
                handleStatus: '0',
                parentsKey: "四氯化碳浓度检测",
              },
              {
                alertID: 12,
                alertGrade: "WARN",
                alertContent: '四氯化碳报警',
                alertTime: '2024-03-20 13:06',
                handleStatus: '0',
                parentsKey: "四氯化碳浓度检测",
              }
            ]
          }
        ]
      }
    ],
    color: "rgba(139, 215, 247, 1)",
    value: 50,
  }
]);
// 百分比计算
const renderPercent = (percent: number) => {
  let total = 0;
  for (let i = 0; i < thetypeofalgorithm.value.length; i++) {
    total += thetypeofalgorithm.value[i].value;
  }
  // 四舍五入
  let finallyData = Math.round((percent / total) * 100);
  if (Object.is(finallyData, NaN)) {
    finallyData = 0;
  } else if (Object.is(finallyData, Infinity)) {
    finallyData = 100;
  }
  return finallyData;
};
// 告警数据
let alarmList = ref([
  {
    title: "已处理",
    color: "rgba(14, 168, 235, 1)",
    code: "AI_ALERT_MESSAGE_DETAIL_TODAY_DEAL_EVENT",
    value: 12,
  },
  {
    title: "未处理",
    color: "rgba(188, 188, 188, 1)",
    code: "AI_ALERT_MESSAGE_DETAIL_TODAY_UNDEAL_EVENT",
    value: 5,
  },
]);
// 告警数量未处理
const UNDEAL = async () => {
  // AI_ALERT_TODAY_UNDEAL_FOR_ALG告警数量未处理
  // 封装请求格式
  let config = [];
  thetypeofalgorithm.value.forEach((item) => {
    if (item.algorithm_name.length > 0) {
      item.algorithm_name.forEach((element, index) => {
        config.push({
          code: "AI_ALERT_TODAY_UNDEAL_TIME_FOR_ALG",
          key: `AI_ALERT_TODAY_UNDEAL_TIME_FOR_ALG_${element.code}`,
          params: {
            algCode: element.code,
            equipmentIds: getsessionStorage(),
          },
        });

        element.key = `AI_ALERT_TODAY_UNDEAL_TIME_FOR_ALG_${element.code}`;
      });
    }
  });
  // 数组对象去重
  config = config.filter((item, index, self) => {
    return (
      index ===
      self.findIndex((t) => {
        return t.params.algCode === item.params.algCode;
      })
    );
  });
  // 去重后格式请求
  if (config.length > 0) {
    let res = (await NewGeneral(config)) as any;
    if (res.code == 200) {
      // 判断对象是否为空
      if (Object.keys(res.data).length === 0) {
        return;
      }
      thetypeofalgorithm.value.forEach((item) => {
        if (item.algorithm_name.length > 0) {
          // 处理子集数据
          item.algorithm_name.forEach((element) => {
            // 查找和返回数据对象里的一样的值
            for (let resKey in res.data) {
              if (res.data[resKey].key === element.key) {
                element.undo = res.data[resKey].data.value;
                // 将获取的UTC字符串转换为北京时间
                element.time =
                  res.data[resKey].data.time == null
                    ? null
                    : new Date(
                      res.data[resKey].data.time
                    ).toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" });
              }
            }
          });
        }
      });
      // 按照时间进行排序从最新时间到最旧时间
      thetypeofalgorithm.value.forEach((item) => {
        if (item.algorithm_name.length > 0) {
          item.algorithm_name.sort((a, b) => {
            return new Date(b.time).getTime() - new Date(a.time).getTime();
          });
        }
      });
    }
  }
};
// 随机生成100以内的整数
const random = (min, max) => {
  return Math.floor(Math.random() * (max - min + 1) + min);
};
const timer = ref(null);
// 告警数量统计
const TOTAL = async () => {
  if (timer.value) {
    clearInterval(timer.value);
  }

  // AI_ALERT_TODAY_FOR_ALG告警数量统计
  // 封装请求格式
  let seriesData = [];
  let config = [];
  let total = 0;
  thetypeofalgorithm.value.forEach((item) => {
    if (item.algorithm_name.length > 0) {
      item.algorithm_name.forEach((element, index) => {
        config.push({
          code: "AI_ALERT_TODAY_FOR_ALG",
          key: `AI_ALERT_TODAY_FOR_ALG${element.code}`,
          params: {
            algCode: element.code,
            equipmentIds: getsessionStorage(),
          },
        });
        element.key = `AI_ALERT_TODAY_FOR_ALG${element.code}`;
      });
    }
  });
  // 数组对象去重
  config = config.filter((item, index, self) => {
    return (
      index ===
      self.findIndex((t) => {
        return t.params.algCode === item.params.algCode;
      })
    );
  });
  // 去重后格式请求
  if (config.length > 0) {
    timer.value = setInterval(() => {
      thetypeofalgorithm.value.forEach((item, index) => {
        if (thetypeofalgorithm.value[index].value !== 0) {
          thetypeofalgorithm.value[index].value = random(1, 100);
        }
      });
    }, 1000);

    let res = (await NewGeneral(config)) as any;
    if (res.code == 200) {
      thetypeofalgorithm.value.forEach((item, index) => {
        thetypeofalgorithm.value[index].value = 0;
      });
      if (Object.keys(res.data).length === 0) {
        return;
      }
      clearInterval(timer.value);
      thetypeofalgorithm.value.forEach((item) => {
        // 父级数据先初始化
        if (item.algorithm_name.length > 0) {
          item.algorithm_name.forEach((element) => {
            // 查找和返回数据对象里的一样的值
            for (let key in res.data) {
              if (key === element.key) {
                element.total = res.data[key].data;
              }
            }

            // 处理父级告警统计数据
            if (item.key == element.parentsKey) {
              item.value += element.total;
            }
          });
        }
      });

      thetypeofalgorithm.value.forEach((item) => {
        total += item.value;
        seriesData.push({
          name: item.key,
          value: item.value,
        });
      });
      console.log(thetypeofalgorithm.value, "typeList");
      valueTotal.value = total;
      // state.AlarmStatisticsOptions.series[0].data = seriesData;

      // state.AlarmStatisticsOptions.title[0].subtext = "" + total;
    }
  }
};
const valueTotal = ref(0);
// 今日处理与未处理
const getAlarmData = async () => {
  let config = [];
  alarmList.value.forEach((item) => {
    config.push({
      code: item.code,
      params: {
        equipmentIds: getsessionStorage(),
      },
    });
  });
  // 数组对象去重
  config = config.filter((item, index, self) => {
    return (
      index ===
      self.findIndex((t) => {
        return t.code === item.code;
      })
    );
  });

  if (config.length > 0) {
    let res = (await NewGeneral(config)) as any;
    if (res.code == 200) {
      if (Object.keys(res.data).length === 0) {
        return;
      }
      alarmList.value.forEach((item) => {
        for (let key in res.data) {
          if (key == item.code) {
            item.value = res.data[key].data;
          }
        }
      });
    }
  }
};

const change = (index) => {
  tabIndex.value = index;
};
// 初始化
const initData = () => {
  //并发
  const limit = pLimit(1);
  //获取 首页3个统计数据
  const input = [
    limit(() => UNDEAL()),
    limit(() => TOTAL()),
    limit(() => getAlarmData()),
  ];
  Promise.all(input);
};
// 创建一个轮询器
const PollingTimer = ref(null);
const PollingFunction = () => {
  if (PollingTimer.value) {
    clearInterval(PollingTimer.value);
  }
  PollingTimer.value = setInterval(() => {
    initData();
  }, 30000);
};
onMounted(() => {
  // 加载数据
  nextTick(() => {
    // initData();
    // PollingFunction();
    // emits.on("HANDLE_MESSAGE", initData);
    emits.on('TEST_HANDLE_MESSAGE', res => {
      // console.log('TEST_HANDLE_MESSAGE====================>', res);
      thetypeofalgorithm.value.forEach((item, index) => {
        if (item.key == res['告警父级']) {
          item.algorithm_name.forEach((k, i) => {
            k.data.forEach((a, b) => {
              a.resetList.forEach((c, d) => {
                if (c.alertID == res['告警ID']) {
                  a.resetList.splice(d, 1)
                }
              })
            })
          })
        }
      });

      console.log(thetypeofalgorithm.value);
      
    });
    let seriesData = [];

    let total = 0;
    thetypeofalgorithm.value.forEach((item) => {
      total += item.value;
      seriesData.push({
        name: item.key,
        value: item.value,
      });
    });
    state.AlarmStatisticsOptions.series[0].data = seriesData;
    state.AlarmStatisticsOptions.title[0].subtext = "" + total;
  });
});
// 销毁计时器
onUnmounted(() => {
  emits.off('TEST_HANDLE_MESSAGE')
  // emits.off("HANDLE_MESSAGE", initData);
  // if (PollingTimer.value) {
  //   clearInterval(PollingTimer.value);
  // }
  // clearInterval(timer.value);
});
</script>
<style lang="scss" scoped>
.alarm-type-statistics {
  width: 100%;
  height: 100%;
  padding: 5px;
  padding-bottom: 0;
  box-sizing: border-box;
  position: relative;
  // 溢出
  // overflow-y: auto;
  // scrollbar-width: none;
  // -ms-overflow-style: none;

  // &::-webkit-scrollbar {
  //   display: none;
  //   /* Chrome Safari */
  // }
  @keyframes move {
    0% {
      transform: translate(-50%, -50%) rotate(0deg);
    }

    100% {
      transform: translate(-50%, -50%) rotate(360deg);
    }
  }

  .top-line {
    width: 100%;
    height: clamp(11.25rem, 9.38vw, 22.5rem);
    display: flex;

    .chart-container {
      width: 60%;
      height: 100%;
      position: relative;

      .route {
        position: absolute;
        top: 50%;
        left: 50%;
        border-radius: 50%;
        transform: translate(-50%, -50%);
        border: 6px dotted rgba(14, 168, 235, 1);
        width: clamp(8.25rem, 6.88vw, 16.5rem);
        height: clamp(8.25rem, 6.88vw, 16.5rem);
        animation: move 10s linear infinite;
      }
    }

    .chart-data {
      width: 40%;
      height: 100%;

      display: flex;
      flex-direction: column;
      justify-content: center;

      .chart-data-item {
        width: 100%;
        height: 20%;
        margin-bottom: 10px;

        &:last-child {
          margin-bottom: 0;
        }

        .topic {
          width: 100%;
          height: 50%;
          display: flex;
          align-items: center;

          .title {
            font-size: clamp(0.875rem, 0.73vw, 1.75rem);
            color: rgba(207, 241, 255, 1);
          }

          .circle {
            width: 8px;
            height: 8px;
            border-radius: 2.5px;
            margin-right: 5px;
            background-color: rgba(0, 148, 255, 1);
          }
        }

        .data {
          width: 100%;
          height: 50%;
          display: flex;
          align-items: center;

          .text-number {
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: clamp(0.875rem, 0.73vw, 1.75rem);
            color: white;
            margin-left: 14px;
            margin-right: 5px;
          }

          .percent-number {
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: clamp(0.875rem, 0.73vw, 1.75rem);
            color: rgba(0, 148, 255, 1);
          }
        }
      }
    }
  }

  .alarm-container {
    width: 100%;
    height: fit-content;
    display: flex;
    margin-top: 20px;

    .list-tab {
      height: 100%;
      display: flex;
      justify-content: start;

      .tab-item {
        padding: clamp(0.5rem, 0.42vw, 1rem) clamp(0.938rem, 0.78vw, 1.875rem);
        color: rgba(136, 136, 136, 1);
        background-color: rgba(51, 51, 51, 0.6);
        border: 1px solid rgba(136, 136, 136, 1);
        box-sizing: border-box;
        cursor: pointer;
      }

      .currentIndex {
        color: rgba(38, 190, 255, 1);
        border-color: rgba(38, 190, 255, 1);
        background-color: rgba(15, 76, 102, 0.6);
      }
    }

    .alarm-item {
      width: 46%;
      height: 80%;

      display: flex;
      align-items: center;
      flex-direction: column;
      justify-content: center;
      background-color: rgba(8, 75, 128, 0.4);
      color: white;

      .title {
        font-size: clamp(1.125rem, 0.94vw, 2.25rem);
        font-weight: bold;
      }

      .number {
        font-size: clamp(1.75rem, 1.46vw, 3.5rem);
        font-family: Microsoft YaHei, Microsoft YaHei;
        font-weight: bold;
        color: #e2f2ff;
        letter-spacing: 2px;
        text-shadow: 0px 0px 6px #26beff;
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }
  }

  .type-list {
    width: 100%;
    height: auto;
    margin-top: clamp(1.875rem, 1.56vw, 3.75rem);
  }

  .alert-list {
    // margin-top: clamp(1.875rem, 1.56vw, 3.75rem);
  }
}

.handle-num {
  width: 100%;
  display: flex;
  align-items: center;

  .nums-item {
    display: flex;
    justify-content: center;
    align-items: center;
    background: url("../../../../assets/image/dashboard/背景.png") center no-repeat;
    height: clamp(3rem, 2.5vw, 6rem);
    width: 50%;

    .num-item-value {
      margin-left: clamp(1rem, 0.83vw, 2rem);
      font-weight: bold;
      font-size: clamp(1rem, 0.83vw, 2rem);
    }
  }
}
</style>
